package net.csdn.www;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 类的说明：生产者-消费者问题.<br>
 * 
 * @author liuzd
 * 
 */
public class Test13 {

	public Test13() {
	}

	/**
	 * 刘柱栋 2013-3-7
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		String path = "F://test4" + File.separator + "ProducterAndConsumer.txt";
		FileUtli.setFilePath(path);
		Queue queue = new Queue();
		ExecutorService es = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 5; i++) {
			es.execute(new Producter("producter_" + i, queue));
			es.execute(new Consumer("consumer_" + i, queue));
//			new Thread(new Producter("producter_" + i, queue)).start();
//			new Thread(new Consumer("consumer_" + i, queue)).start();
		}
		es.shutdown();
		// // test SimpleDateFormat format date to millisecond
		// SimpleDateFormat dateFormat = new
		// SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");
		// String str = dateFormat.format(new Date());
		// System.out.println(str);
	}

}

class FileUtli {
	private static SimpleDateFormat dateFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss:ms");

	private static String filePath;

	public static void setFilePath(String path) {
		filePath = path;
		int end = path.lastIndexOf(File.separator);
		path = path.substring(0, end);
		File file = new File(path);
		if(!file.exists()){
			file.mkdirs();
		}
	}

	public static void outPutStringToFile(String str) {
		if (!isNotNull(filePath)) {
			return;
		}
		File file = new File(filePath);
		FileOutputStream outPutStream = null;
		str = getDateTimeStr() + str + " \r\n";
		try {
			outPutStream = new FileOutputStream(file, true);
			byte[] charBytes = str.getBytes();
			outPutStream.write(charBytes);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("=====================" + e);
		} finally {
			try {
				if (outPutStream != null) {
					outPutStream.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("=====================" + e);
			} finally {
				outPutStream = null;
			}

		}
	}

	private static boolean isNotNull(String str) {
		if (str == null) {
			return false;
		} else if ("".equals(str)) {
			return false;
		} else {
			return true;
		}
	}

	private static String getDateTimeStr() {
		String str = dateFormat.format(new Date());
		return str + ":::";
	}

}

class Queue {
	private int value = 0;

	public int getValue() {
		return value;
	}

	// private boolean flag = false;

	public synchronized void put(String name) {
		if (value < 10) {
			value++;
			String str = name + "****Put The Item : " + value;
			FileUtli.outPutStringToFile(str);
			notify();
		} else {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public synchronized void get(String name) {
		if (value == 0) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} else if (value < 5) {
			value--;
			String str = name + "====Get The Item : " + value;
			FileUtli.outPutStringToFile(str);
			// System.out.println(name + "====Get The Item : " + value);
			notify();
		} else {
			value--;
			String str = name + "====Get The Item : " + value;
			FileUtli.outPutStringToFile(str);
		}

	}
}

class Producter implements Runnable {
	private Queue queue;
	private String name;

	public Producter() {

	}

	public Producter(String name, Queue queue) {
		this.name = name;
		this.queue = queue;
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			create();
		}
	}

	private void create() {
		queue.put(name);
	}

}

class Consumer implements Runnable {
	private Queue queue;
	private String name;

	public Consumer() {
	}

	public Consumer(String name, Queue queue) {
		this.name = name;
		this.queue = queue;
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			consume();
		}
	}

	private void consume() {
		queue.get(name);
	}

}
